package com.lm.caffeine.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
public class CacheConfig {

    /**
     * SimpleCacheManager:
     *    这种缓存管理器允许你在应用程序启动时通过配置多个CaffeineCache来创建多个缓存。
     *    这种方式可以让你为每个方法单独配置缓存过期时间。
     * @Author shdxhl
     * @Method  caffeineCacheManager
     * @Date 9:13 2023-06-13
     * @Param []
     * @return void
     **/
//    @Bean
//    public CacheManager caffeineCacheManager() {
//        SimpleCacheManager cacheManager = new SimpleCacheManager();
//        List<CaffeineCache> caches = new ArrayList<>();
//        caches.add(new CaffeineCache("usersCache",
//                Caffeine.newBuilder().expireAfterWrite(5, TimeUnit.SECONDS).build()));
//        caches.add(new CaffeineCache("productsCache",
//                Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build()));
//        cacheManager.setCaches(caches);
//        return cacheManager;
//    }

    /**
     * CaffeineCacheManager：
     *   这种缓存管理器使用了一个全局的Caffeine配置来创建所有的缓存。
     *   这种方式不能为每个方法单独配置缓存过期时间，但是可以在程序启动时配置全局的缓存配置，这样就可以轻松地设置所有方法的缓存过期时间。
     * @Author shdxhl
     * @Method  cacheManager
     * @Date 9:13 2023-06-13
     * @Param []
     * @return void
     **/
    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
                // 初始大小
                .initialCapacity(10)
                // 最大容量
                .maximumSize(100)
                // 打开统计
                .recordStats()
                // 5分钟不访问自动丢弃
                .expireAfterAccess(5, TimeUnit.MINUTES);
        caffeineCacheManager.setCaffeine(caffeine);
        // 设定缓存器名称
        caffeineCacheManager.setCacheNames(getCacheNames());
        // 值不可为空
        caffeineCacheManager.setAllowNullValues(false);
        return caffeineCacheManager;
    }

    private static List<String> getCacheNames() {
        List<String> names = new ArrayList<>(1);
        names.add("usersCache");
        names.add("productsCache");
        return names;
    }
}
